﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Training.Domain;
using Training.Domain.Exception;
using Training.Domain.Formatters;
using Training.Domain.Repositories;

namespace Training.Data.Repositories
{
    public abstract class GenericCsvRepository<T> : IGenericRepository<T>
        where T : Entity
    {
        private string CsvData
        {
            get 
            {
                Type typeParameterType = typeof(T);
                return ConfigurationManager.AppSettings[typeParameterType.Name + ".CsvData"]; 
            } 
        }

        protected abstract string GetString(T t);
        protected abstract T GetEntity(string l);

        public IEnumerable<T> GetAll()
        {            
            var lines = File.ReadAllLines(CsvData);
            return lines.Select(l => GetEntity(l));
        }

        public T Save(T obj)
        {
            var list = GetAll().ToList();
            var existing = list.SingleOrDefault(t => t.Id == obj.Id);
            if (existing != null)
                list.Remove(obj);

            list.Add(obj);
            Save(list);
            return obj;
        }
        
        public void Remove(Guid id)
        {
            var allItems = GetAll().ToList();
            var item = allItems.SingleOrDefault(t => t.Id == id);
            if (item == null)
                throw new ItemNotFoundException();

            allItems.Remove(item);
            Save(allItems);
        }

        private void Save(List<T> list)
        {
            var lines = list.Select(t => GetString(t));
            File.WriteAllLines(CsvData, lines);
        }
    }
}
